<template>
  <div style="overflow: hidden">
    <canvas id="adjustCanvas" :width="imgWidth" :height="imgHeight"></canvas>

    <div style="margin: 10px 0; display: flex; flex-direction: column; gap: 15px;">
      <div>
        <span>亮度: {{ brightness }}</span>
        <a-slider v-model="brightness" :min="-100" :max="100" :step="1" @change="updateImage" />
      </div>

      <div>
        <span>对比度: {{ contrast }}</span>
        <a-slider v-model="contrast" :min="-100" :max="100" :step="1" @change="updateImage" />
      </div>

      <div>
        <span>饱和度: {{ saturation }}</span>
        <a-slider v-model="saturation" :min="-100" :max="100" :step="1" @change="updateImage" />
      </div>

      <div>
        <span>清晰度: {{ sharpness }}</span>
        <a-slider v-model="sharpness" :min="-100" :max="100" :step="1" @change="updateImage" />
      </div>
    </div>

    <a-button type="primary" @click="save" style="margin-top: 20px; float: right">保存</a-button>
  </div>
</template>

<script>
export default {
  props: ['nowImg'],
  data() {
    return {
      imgWidth: '',
      imgHeight: '',
      originalImageData: null,
      brightness: 0,
      contrast: 0,
      saturation: 0,
      sharpness: 0,
      canvas: null,
      ctx: null
    }
  },
  watch: {
    // 监听图片变化
    nowImg: {
      immediate: true,
      handler() {
        // this.initCanvas()
        this.loadImage()
      }
    }
  },
  mounted() {
    this.initCanvas()
    this.loadImage()
  },
  methods: {
    initCanvas() {
      this.canvas = document.getElementById('adjustCanvas');
      this.ctx = this.canvas.getContext('2d');
    },

    loadImage() {
      const img = new Image();
      img.src = this.nowImg;
      img.setAttribute("crossOrigin", "Anonymous");

      img.onload = () => {
        // 等比例缩放图片
        const maxWidth = 500;
        let width = img.width;
        let height = img.height;

        if (width > maxWidth) {
          const ratio = maxWidth / width;
          width = maxWidth;
          height = height * ratio;
        }

        this.imgWidth = width;
        this.imgHeight = height;
        this.canvas.width = width;
        this.canvas.height = height;

        // 绘制原始图像并保存像素数据
        this.ctx.drawImage(img, 0, 0, width, height);
        this.originalImageData = this.ctx.getImageData(0, 0, width, height);

        // 初始渲染
        this.updateImage();
      };
    },

    updateImage() {
      if (!this.originalImageData) return;

      // 创建新的ImageData实例，而不是使用JSON复制
      const { width, height, data } = this.originalImageData;
      const imageData = new ImageData(new Uint8ClampedArray(data), width, height);
      const imgData = imageData.data;
      const len = imgData.length / 4; // 每个像素4个通道(RGBA)

      // 应用亮度调整
      if (this.brightness !== 0) {
        for (let i = 0; i < len; i++) {
          const index = i * 4;
          imgData[index] = Math.min(255, Math.max(0, imgData[index] + this.brightness));
          imgData[index + 1] = Math.min(255, Math.max(0, imgData[index + 1] + this.brightness));
          imgData[index + 2] = Math.min(255, Math.max(0, imgData[index + 2] + this.brightness));
        }
      }

      // 应用对比度调整
      if (this.contrast !== 0) {
        const factor = (100 + this.contrast) / 100;
        const mid = 128 * (259 * (factor + 1)) / (255 * (100 - factor));

        for (let i = 0; i < len; i++) {
          const index = i * 4;
          imgData[index] = Math.min(255, Math.max(0, mid + (imgData[index] - 128) * factor));
          imgData[index + 1] = Math.min(255, Math.max(0, mid + (imgData[index + 1] - 128) * factor));
          imgData[index + 2] = Math.min(255, Math.max(0, mid + (imgData[index + 2] - 128) * factor));
        }
      }

      // 应用饱和度调整
      if (this.saturation !== 0) {
        let sat;
        if (this.saturation >= 0) {
          sat = 1 + this.saturation / 50;
        } else {
          sat = 1 + this.saturation / 100;
        }

        const width = imageData.width;
        const height = imageData.height;
        const imgData = imageData.data;
        const len = imgData.length / 4;

        for (let i = 0; i < len; i++) {
          const index = i * 4;
          const r = imgData[index];
          const g = imgData[index + 1];
          const b = imgData[index + 2];

          const gray = 0.299 * r + 0.587 * g + 0.114 * b;

          imgData[index] = Math.min(255, Math.max(0, r * sat + gray * (1 - sat)));
          imgData[index + 1] = Math.min(255, Math.max(0, g * sat + gray * (1 - sat)));
          imgData[index + 2] = Math.min(255, Math.max(0, b * sat + gray * (1 - sat)));
        }
      }

      // 应用清晰度调整
      if (this.sharpness !== 0) {
        const amount = this.sharpness / 50; // 增强锐化强度
        const width = imageData.width;
        const height = imageData.height;
        const imgData = imageData.data;
        const newData = new Uint8ClampedArray(imgData.length);

        const kernel = [
          -1, -1, -1,
          -1,  9, -1,
          -1, -1, -1
        ];

        for (let y = 1; y < height - 1; y++) {
          for (let x = 1; x < width - 1; x++) {
            let r = 0, g = 0, b = 0;

            for (let ky = 0; ky < 3; ky++) {
              for (let kx = 0; kx < 3; kx++) {
                const kernelIndex = ky * 3 + kx;
                const imgIndex = ((y + ky - 1) * width + (x + kx - 1)) * 4;

                r += imgData[imgIndex] * kernel[kernelIndex];
                g += imgData[imgIndex + 1] * kernel[kernelIndex];
                b += imgData[imgIndex + 2] * kernel[kernelIndex];
              }
            }

            const index = (y * width + x) * 4;
            newData[index] = Math.min(255, Math.max(0, imgData[index] + amount * r));
            newData[index + 1] = Math.min(255, Math.max(0, imgData[index + 1] + amount * g));
            newData[index + 2] = Math.min(255, Math.max(0, imgData[index + 2] + amount * b));
            newData[index + 3] = imgData[index + 3];
          }
        }

        // 边缘处理
        for (let y = 0; y < height; y++) {
          for (let x = 0; x < width; x++) {
            const index = (y * width + x) * 4;
            if (x === 0 || x === width - 1 || y === 0 || y === height - 1) {
              newData[index] = imgData[index];
              newData[index + 1] = imgData[index + 1];
              newData[index + 2] = imgData[index + 2];
              newData[index + 3] = imgData[index + 3];
            }
          }
        }

        const newImageData = new ImageData(newData, width, height);
        this.ctx.putImageData(newImageData, 0, 0);
      }

      // 绘制更新后的图像
      this.ctx.putImageData(imageData, 0, 0);
    },

    save() {
      // 将处理后的图像转换为DataURL
      const imgUrl = this.canvas.toDataURL('image/png');
      // 转换为File对象
      const file = this.dataURLtoFile(imgUrl, 'adjusted-img');
      // 发送给父组件
      this.$emit('updateImg', file);
    },

    dataURLtoFile(dataurl, filename = 'file') {
      const arr = dataurl.split(',');
      const mime = arr[0].match(/:(.*?);/)[1];
      const suffix = mime.split('/')[1];
      const bstr = atob(arr[1]);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);

      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }

      return new File([u8arr], `${filename}.${suffix}`, { type: mime });
    }
  }
}
</script>

<style scoped>
#adjustCanvas {
  margin-bottom: 15px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}
</style>